home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_497 / newshellcx / newshellcx.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  13KB  |  452 lines

  1. /*
  2.  *  NewShellCX.c
  3.  *
  4.  *  Commodity
  5.  *
  6.  *  Author: Stefan Sticht
  7.  *
  8.  *  Copyright: source is public domain, no copyright
  9.  *
  10.  *  Version history:
  11.  *
  12.  *  V1.01   initial release
  13.  *  V1.03   recompiled with main.c V1.02
  14.  *  V1.04   completly rewritten; shared commodity code thrown away; smaller, uses less CPU time
  15.  *  V1.05   some really minor changes
  16.  */
  17.  
  18. #define VERSION "V1.05"
  19.  
  20. /********************************************************************
  21.  *                             interfacing                          *
  22.  ********************************************************************/
  23.  
  24. /*
  25.  *  include files
  26.  */
  27.  
  28. #include <stdarg.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <dos/dos.h>
  32. #include <dos/dostags.h>
  33. #include <libraries/commodities.h>
  34.  
  35. #include <clib/alib_protos.h>
  36. #include <clib/commodities_protos.h>
  37. #include <pragmas/commodities_pragmas.h>
  38. #include <clib/dos_protos.h>
  39. #include <pragmas/dos_pragmas.h>
  40. #include <clib/exec_protos.h>
  41. #include <pragmas/exec_pragmas.h>
  42. #include <clib/intuition_protos.h>
  43. #include <pragmas/intuition_pragmas.h>
  44.  
  45. #ifdef DEBUG
  46. #define printf KPrintF
  47. #include <clib/dlib_protos.h>
  48. #endif
  49.  
  50. /*
  51.  *  prototypes
  52.  */
  53. long request(char *title, char *gadgets, char *text, ...);
  54. struct Library *myopenlibrary(char *name, unsigned long version);
  55. void processmessages(void);
  56.  
  57. /*
  58.  *  global data defined in other moduls
  59.  *
  60.  *  libraries opened by startup code; basepointers needed by function pragmas
  61.  */
  62. extern struct Library *DOSBase;
  63. extern struct Library *SysBase;
  64.  
  65. /*
  66.  *  Disable SAS/C CTRL/C handling
  67.  */
  68. void chkabort(void) {}
  69.  
  70. /********************************************************************
  71.  *                             global data                          *
  72.  ********************************************************************/
  73.  
  74. /*
  75.  *  definition of all messages (multi language support not completed yet)
  76.  */
  77. #ifdef GERMAN
  78.  
  79. #define RETRY_GADGETS           "Wiederholen|Abbrechen"
  80. #define RESUME_GADGETS          "Weiter"
  81. #define MSG_LIBRARY_OPENERR     "Die %s (V%ld+) kann nicht geöffnet werden!"
  82. #define COM_NAME                "NewShellCX"
  83. #define COM_DESCR               "Öffnet eine neue Shell mit "
  84. #define TT_HOTKEY               "TASTE"
  85. #define TT_COMMAND              "KOMMANDO"
  86. #define NO                      "NEIN"
  87. #define YES                     "JA"
  88.  
  89. #else
  90.  
  91. #define RETRY_GADGETS           "Retry|Cancel"
  92. #define RESUME_GADGETS          "Resume"
  93. #define MSG_LIBRARY_OPENERR     "%s (V%ld+) can't be opened!"
  94. #define COM_NAME                "NewShellCX"
  95. #define COM_DESCR               "Open new shell on "
  96. #define TT_HOTKEY               "HOTKEY"
  97. #define TT_COMMAND              "COMMAND"
  98. #define YES                     "YES"
  99. #define NO                      "NO"
  100.  
  101. #endif
  102.  
  103. #define COM_TITLE           COM_NAME " " VERSION
  104. #define CX_PRIORITY         "CX_PRIORITY"
  105. #define DEF_CX_PRIORITY     0
  106.  
  107. #define DEF_TT_HOTKEY       "lcommand esc"
  108. #define DEF_TT_COMMAND      "NewShell"
  109.  
  110. /*
  111.  *  library base pointers
  112.  */
  113. struct Library *IntuitionBase;
  114. struct Library *CxBase;
  115. struct Library *IconBase;
  116.  
  117. /*
  118.  *  message port
  119.  */
  120. struct MsgPort *cxport = NULL;
  121.  
  122. /*
  123.  *  signal flag
  124.  */
  125. unsigned long cxsigflag = 0l;
  126.  
  127. /*
  128.  *  programtitle and version for Version command
  129.  */
  130. char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
  131.  
  132. /*
  133.  *  helpstring
  134.  */
  135. #ifdef GERMAN
  136. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
  137.                     "Aufruf: " COM_NAME " [" CX_PRIORITY "=<n>] [" TT_HOTKEY "=<Eingabe>] ["\
  138.                     TT_COMMAND "=<Datei>]\n";
  139. #else
  140. char helpstring[] = "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
  141.                     "Usage: " COM_NAME " [" CX_PRIORITY "=<n>] [" TT_HOTKEY "=<input>] ["\
  142.                     TT_COMMAND "=<file>]\n";
  143. #endif
  144.  
  145. /*
  146.  *  the tooltypearray
  147.  */
  148. char **tooltypes;
  149.  
  150. /*
  151.  *  our broker
  152.  */
  153. CxObj *broker = NULL;
  154.  
  155. /*
  156.  *  our commodity description
  157.  */
  158. char descr[CBD_DESCRLEN + 1] = COM_DESCR;
  159.  
  160. /*
  161.  *  the command
  162.  */
  163. char *command;
  164.  
  165. struct NewBroker newbroker = {
  166.     NB_VERSION,                         /* BYTE nb_Version               */
  167.     COM_NAME,                           /* BYTE *nb_Name                 */
  168.     COM_TITLE,                          /* BYTE *nb_Title                */
  169.     descr,                              /* BYTE *nb_Descr                */
  170.     NBU_NOTIFY | NBU_UNIQUE,            /* SHORT nb_Unique               */
  171.     0,                                  /* SHORT nb_Flags                */
  172.     0,                                  /* BYTE nb_Pri                   */
  173.     NULL,                               /* struct MsgPort nb_Port        */
  174.     0                                   /* WORD nb_ReservedChannel       */
  175. };
  176.  
  177. #define NEWSHELL 1
  178.  
  179. /*
  180.  *  TagItem structure for System()
  181.  */
  182. #define P_SYS_Input     0
  183. #define P_SYS_Output    1
  184. struct TagItem systemtags[] = {
  185.     SYS_Input, 0l,
  186.     SYS_Output, 0l,
  187.     SYS_Asynch, TRUE,
  188.     SYS_UserShell, TRUE,
  189.     TAG_DONE
  190.     };
  191.  
  192. /********************************************************************
  193.  *                             functions                            *
  194.  ********************************************************************/
  195.  
  196. /*
  197.  *  request(): a glue routine to EasyRequest as simple as printf plus
  198.  *             titlestring, gadgettexts
  199.  *
  200.  *  Input: char *title:         pointer to the title of the requester
  201.  *         char *gadgets:       pointer to gadgettext
  202.  *         char *text:          text displayed in requester
  203.  *
  204.  *  Result: same as EasyrequestArgs()
  205.  *
  206.  * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
  207.  */
  208. long request(char *title, char *gadgets, char *text, ...)
  209. {
  210.     /*
  211.      *  structure textreq only needed in this function, so hide it here
  212.      *  must be static, in order to be initialized only once
  213.      */
  214.     static struct EasyStruct textreq = {
  215.         sizeof (struct EasyStruct), /* ULONG es_StructSize      */
  216.         0l,                         /* ULONG es_Flags           */
  217.         NULL,                       /* UBYTE *es_Title          */
  218.         NULL,                       /* UBYTE *es_TextFormat     */
  219.         NULL,                       /* UBYTE *es_GadgetFormat   */
  220.         };
  221.     va_list ap;
  222.     long rc;
  223.  
  224.     /*
  225.      *  get start of variable arguments
  226.      */
  227.     va_start(ap, text);
  228.  
  229.     /*
  230.      *  update textreq
  231.      */
  232.     textreq.es_Title = (UBYTE *)title;
  233.     textreq.es_TextFormat = (UBYTE *)text;
  234.     textreq.es_GadgetFormat = (UBYTE *)gadgets;
  235.  
  236.     /*
  237.      *  win may be NULL
  238.      */
  239.     rc = EasyRequestArgs(NULL, &textreq, NULL, ap);
  240.  
  241.     va_end(ap);
  242.  
  243.     return(rc);
  244. }
  245.  
  246. /*
  247.  *  myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
  248.  *                   if OpenLibrary() fails, to give the user a chance to
  249.  *                   copy the library to libs: and retry
  250.  *                   requires request(), see above
  251.  */
  252. struct Library *myopenlibrary(char *name, unsigned long version)
  253. {
  254.     static char errortext[] = MSG_LIBRARY_OPENERR;
  255.     struct Library *libptr;
  256.     long ok = TRUE;
  257.  
  258.     do {
  259.         if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
  260.             if (IntuitionBase) {
  261.                 ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version);
  262.                 }
  263.             else ok = FALSE;
  264.             }
  265.         } while (!libptr && ok);
  266.  
  267.     #ifdef DEBUG
  268.     printf("myopenlibrary(%s, %ld) = 0x%lx\n", name, version, libptr);
  269.     #endif
  270.     return(libptr);
  271. }
  272.  
  273. void main(int argc, char *argv[])
  274. {
  275.     CxObj *filter;
  276.     char *hotkey;
  277.     struct Message *msg;
  278.     unsigned long len;
  279.  
  280.     if ((argc > 1) && (*argv[1] == '?')) {
  281.         /*
  282.          *  display help string
  283.          */
  284.         Write(Output(), helpstring, sizeof(helpstring) - 1l);
  285.         return;
  286.         }
  287.  
  288.     /*
  289.      *  open required libraries first
  290.      */
  291.     if (IntuitionBase = myopenlibrary("intuition.library", 37l)) {
  292.  
  293.         if (CxBase = myopenlibrary("commodities.library", 37l)) {
  294.  
  295.             if (IconBase = myopenlibrary("icon.library", 37l)) {
  296.  
  297.                 /*
  298.                  * create tooltypes array (requires icon.library open!!!)
  299.                  */
  300.                 tooltypes = (char **)ArgArrayInit(argc, argv);
  301.  
  302.                 /*
  303.                  *  create our message port
  304.                  */
  305.                 if (cxport = CreateMsgPort()) {
  306.  
  307.                     cxsigflag = 1l << cxport->mp_SigBit;
  308.                     /*
  309.                      * set up some broker data
  310.                      */
  311.                     newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY);
  312.                     newbroker.nb_Port = cxport;
  313.  
  314.                     command = ArgString(tooltypes, TT_COMMAND, DEF_TT_COMMAND);
  315.  
  316.                     if ((hotkey = ArgString(tooltypes, TT_HOTKEY, DEF_TT_HOTKEY)) &&
  317.                         *hotkey && command && *command) {
  318.  
  319.                         len = strlen(descr);
  320.                         strncpy(descr + len, hotkey, sizeof(descr) - len - 2l);
  321.  
  322.                         if (broker = CxBroker(&newbroker, NULL)) {
  323.  
  324.                             if (filter = HotKey(hotkey, cxport, NEWSHELL)) {
  325.  
  326.                                 AttachCxObj(broker, filter);
  327.  
  328.                                 if (!CxObjError(filter)) {
  329.  
  330.                                     /*
  331.                                      *  activate our commodity
  332.                                      */
  333.                                     ActivateCxObj(broker, 1l);
  334.                                     /*
  335.                                      *  now watch our numerous ports
  336.                                      */
  337.                                     processmessages();
  338.  
  339.                                     } /* if !CxObjError() */
  340.  
  341.                                 } /* if centerfilter */
  342.  
  343.                             DeleteCxObjAll(broker);
  344.  
  345.                             } /* if broker */
  346.  
  347.                         #ifdef DEBUG
  348.                         else printf("main(): CxBroker() failed!\n");
  349.                         #endif
  350.  
  351.                         } /* if hotkey */
  352.  
  353.                     /*
  354.                      *  delete our message port after replying all pending messages
  355.                      */
  356.                     while (msg = GetMsg(cxport)) ReplyMsg(msg);
  357.                     DeleteMsgPort(cxport);
  358.  
  359.                     } /* if cxport */
  360.  
  361.                 #ifdef DEBUG
  362.                 else printf("main(): CraeteMsgPort() failed!\n");
  363.                 #endif
  364.  
  365.                 ArgArrayDone();
  366.  
  367.                 CloseLibrary(IconBase);
  368.                 } /* if IconBase */
  369.  
  370.             CloseLibrary(CxBase);
  371.             } /* if CxBase */
  372.  
  373.     CloseLibrary(IntuitionBase);
  374.     } /* if IntuitionBase */
  375.  
  376. } /* main() */
  377.  
  378. void processmessages(void)
  379. {
  380.     BPTR fh;
  381.     struct Message *msg;
  382.     unsigned long msgid;
  383.     unsigned long msgtype;
  384.     unsigned long sigreceived;
  385.     unsigned short quit = FALSE;
  386.  
  387.     while (!quit) {
  388.  
  389.         sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag);
  390.  
  391.         #ifdef DEBUG
  392.         printf("processmessages(): signal received\n");
  393.         #endif
  394.  
  395.         if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
  396.  
  397.         if (sigreceived & cxsigflag) {
  398.  
  399.             while (msg = (struct Message *)GetMsg(cxport)) {
  400.  
  401.                 msgid = CxMsgID((CxMsg *)msg);
  402.                 msgtype = CxMsgType((CxMsg *)msg);
  403.  
  404.                 ReplyMsg(msg);
  405.  
  406.                 switch (msgtype) {
  407.  
  408.                     case CXM_IEVENT:
  409.                         switch (msgid) {
  410.  
  411.                             case NEWSHELL:
  412.                                 fh = Open("NIL:", MODE_NEWFILE);
  413.                                 systemtags[P_SYS_Input].ti_Data = (ULONG)fh;
  414.                                 fh = Open("NIL:", MODE_NEWFILE);
  415.                                 systemtags[P_SYS_Output].ti_Data = (ULONG)fh;
  416.                                 System(command, systemtags);
  417.                                 break;
  418.  
  419.                             } /* switch msgid */
  420.  
  421.                         break;
  422.  
  423.                     case CXM_COMMAND:
  424.                         switch (msgid) {
  425.  
  426.                             case CXCMD_UNIQUE:
  427.                             case CXCMD_KILL:
  428.                                 quit = TRUE;
  429.                                 break;
  430.  
  431.                             case CXCMD_DISABLE:
  432.                                 ActivateCxObj(broker, 0l);
  433.                                 break;
  434.  
  435.                             case CXCMD_ENABLE:
  436.                                 ActivateCxObj(broker, 1l);
  437.                                 break;
  438.  
  439.                             }
  440.                         break;
  441.  
  442.                     } /* switch msgtype */
  443.  
  444.                 } /* while CxMsg */
  445.  
  446.             } /* if (sigreceived & cxsigflag) */
  447.  
  448.         } /* while !quit */
  449.  
  450.     ActivateCxObj(broker, 0l);
  451. }
  452.